From fd42a0fb6bc1fa7736232b8d984b4fc91f076bbc Mon Sep 17 00:00:00 2001 From: robertl Date: Mon, 22 Sep 2003 01:08:46 +0000 Subject: [PATCH] Add navicache as a (read-only) format. --- gpsbabel/Makefile | 2 +- gpsbabel/README | 9 ++ gpsbabel/navicache.c | 226 +++++++++++++++++++++++++++++++++++++++++++ gpsbabel/testo | 6 ++ gpsbabel/vecs.c | 9 +- 5 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 gpsbabel/navicache.c diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile index a5b16de78..caa6c36fb 100644 --- a/gpsbabel/Makefile +++ b/gpsbabel/Makefile @@ -18,7 +18,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o \ gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \ psp.o holux.o garmin.o tmpro.o tpg.o \ xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o \ - gpilots.o saroute.o + gpilots.o saroute.o navicache.o FILTERS=position.o duplicate.o arcdist.o polygon.o diff --git a/gpsbabel/README b/gpsbabel/README index 87baeab3e..2e94688b2 100644 --- a/gpsbabel/README +++ b/gpsbabel/README @@ -391,6 +391,15 @@ THE FORMATS application. Full details of it's usage are available in the file README.mapconverter. + navicache + + This is the XML format that's used by Navicache.com for their + geocaching data. There are a number of fields in it that are + marked "required" but are Navicache-specific, so GPSBabel can not + write these files, but we can still read them. + + http://www.navicache.com/cgi-bin/ib312a/ikonboard.cgi?act=ST;f=23;t=334 + DATA FILTERS GPSBabel supports data filtering. Data filters are invoked from diff --git a/gpsbabel/navicache.c b/gpsbabel/navicache.c new file mode 100644 index 000000000..3360b4f22 --- /dev/null +++ b/gpsbabel/navicache.c @@ -0,0 +1,226 @@ +/* + Copyright (C) 2003 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#if !NO_EXPAT +#include +static XML_Parser psr; +#endif + +static waypoint *wpt_tmp; + +FILE *fd; +FILE *ofd; + +#define MYNAME "navicache" +#define MY_CBUF 4096 + +#if NO_EXPAT +void +nav_rd_init(const char *fname, const char *args) +{ + fatal(MYNAME ": This build excluded GPX support becuase expat was not installed.\n"); +} + +void +nav_read(void) +{ +} +#else + +struct +nc_type_mapping{ + geocache_type type; + const char *name; +} nc_type_map[] = { + { gt_unknown, "unknown" }, + { gt_traditional, "normal" }, + { gt_multi, "Multi-part" }, + { gt_virtual, "Virtual" }, + { gt_event, "event" } +}; + +struct +nc_container_mapping{ + geocache_container type; + const char *name; +} nc_container_map[] = { + { gc_other, "Unknown" }, + { gc_micro, "Micro" }, + { gc_regular, "Normal" }, + { gc_large, "Large" }, + { gc_virtual, "Virtual" } +}; + +static +geocache_type +nc_mktype(const char *t) +{ + int i; + int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { + return nc_type_map[i].type; + } + } + return gt_unknown; +} + +static +geocache_container +nc_mkcont(const char *t) +{ + int i; + int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { + return nc_container_map[i].type; + } + } + return gc_unknown; +} + +static void +nav_start(void *data, const char *el, const char **attr) +{ + if (0 == strcmp(el, "CacheDetails")) { + wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + const char **ap; + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "cache_id")) { + wpt_tmp->shortname = xstrdup(ap[1]); + } else + if (0 == strcmp(ap[0], "name")) { + wpt_tmp->description = xstrdup(ap[1]); + } else + if (0 == strcmp(ap[0], "latitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->position.latitude.degrees); + } else + if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->position.longitude.degrees); + } else + if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->position.longitude.degrees); + } else + if (0 == strcmp(ap[0], "difficulty")) { + float x; + sscanf(ap[1], "%f", &x); + wpt_tmp->gc_data.diff = x * 10; + } else + if (0 == strcmp(ap[0], "terrain")) { + float x; + sscanf(ap[1], "%f", &x); + wpt_tmp->gc_data.terr = x * 10; + } else + if (0 == strcmp(ap[0], "cache_type")) { + wpt_tmp->gc_data.type = nc_mktype(ap[1]); + } else + if (0 == strcmp(ap[0], "cache_size")) { + wpt_tmp->gc_data.container = nc_mkcont(ap[1]); + } + } + waypt_add(wpt_tmp); + } +} + +static void +nav_end(void *data, const char *el) +{ +} + +void +nav_rd_init(const char *fname, const char *args) +{ + fd = fopen(fname, "r"); + if (fd == NULL) { + fatal(MYNAME ":Cannot open %s for reading\n", fname); + } + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } + + XML_SetElementHandler(psr, nav_start, nav_end); +} + +void +nav_read(void) +{ + int len; + char buf[MY_CBUF]; + + while ((len = fread(buf, 1, sizeof(buf), fd))) { + if (!XML_Parse(psr, buf, len, feof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); +} + +#endif + +void +nav_rd_deinit(void) +{ + fclose(fd); +} + +void +nav_wr_init(const char *fname, const char *args) +{ + fatal(MYNAME ": Does not support writing Navicache files.\n") + ofd = fopen(fname, "w"); + if (ofd == NULL) { + fatal(MYNAME ":Cannot open '%s' for writing\n", fname); + } +} + +void +nav_wr_deinit(void) +{ + fclose(ofd); +} + +static void +nav_waypt_pr(const waypoint *waypointp) +{ +} + +void +nav_write(void) +{ +} + +ff_vecs_t navicache_vecs = { + nav_rd_init, + nav_wr_init, + nav_rd_deinit, + nav_wr_deinit, + nav_read, + nav_write, + NULL +}; diff --git a/gpsbabel/testo b/gpsbabel/testo index 3bef60b53..64bd81954 100755 --- a/gpsbabel/testo +++ b/gpsbabel/testo @@ -328,6 +328,12 @@ ${PNAME} -i gpilots -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/2.gpx compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx #${PNAME} -i easygps -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx +# +# Navicache. +${PNAME} -i navicache -f reference/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wpt +compare ${TMPDIR}/navi.wpt reference/navicache.ref +# + # # Arc Distance filter # diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 155b44649..602bec15c 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -53,6 +53,7 @@ extern ff_vecs_t easygps_vecs; extern ff_vecs_t quovadis_vecs; extern ff_vecs_t gpilots_vecs; extern ff_vecs_t saroute_vecs; +extern ff_vecs_t navicache_vecs; static vecs_t vec_list[] = { @@ -192,9 +193,15 @@ vecs_t vec_list[] = { { &saroute_vecs, "saroute", - "Delorme Street Atlast Route", + "Delorme Street Atlas Route", ".anr" }, + { + &navicache_vecs, + "navicache", + "Navicache.com XML", + NULL + }, { NULL, NULL, -- 2.30.2